package com.example.service.user.impl;

import com.example.config.ProjectProperties;
import com.example.dao.CacheDao;
import com.example.exception.InvalidTokenException;
import com.example.pojo.User;
import com.example.service.user.UserAuthorizationService;
import com.example.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author LeXin Huang
 * @date 2021年03月22日 20:41
 */
@Service
public class UserAuthorizationServiceImpl implements UserAuthorizationService {

    private final CacheDao cacheDao;

    private final long tokenTimeOut;

    private final TimeUnit tokenTimeUnit;

    public UserAuthorizationServiceImpl(CacheDao cacheDao, ProjectProperties projectProperties) {
        this.cacheDao = cacheDao;
        this.tokenTimeOut = projectProperties.getToken().getTimeOut();
        this.tokenTimeUnit = projectProperties.getToken().getTimeUnit();
    }

    @Override
    public void removeUserTokenByUsername(String username) {
        String token = null;
        if (null != username) {
            token = cacheDao.getString(username);
            cacheDao.deleteString(username);
        }
        if (null != token) {
            cacheDao.deleteUserCache(token);
        }
    }

    @Override
    public void logout(String token) {
        if (null == token) {
            throw new InvalidTokenException("用户未登录!");
        }
        User user = cacheDao.getUserCache(token);
        if (null == user) {
            throw new InvalidTokenException("用户未登录!");
        }
        removeUserTokenByUsername(user.getUsername());
    }

    @Override
    public void refreshUserTokenCache(@NotNull(value = "刷新用户token时, 传递的 token 不能为 null!") String token,
                                      @NotNull(value = "刷新用户token时, 传递的 user 不能为 null!") User user) {

        Objects.requireNonNull(user.getUsername(), "刷新用户token时, user 的 username 不能为 null!");
        cacheDao.set(token, user, this.tokenTimeOut, this.tokenTimeUnit);
        cacheDao.set(user.getUsername(), token, this.tokenTimeOut, this.tokenTimeUnit);
    }

    @Override
    public String authorize(User user) {
        Objects.requireNonNull(user, "授权的对象 user 不能为 null!");
        Objects.requireNonNull(user.getUsername(), "授权对象的用户名不能为 null!");
        String token = cacheDao.getString(user.getUsername());
        if (null == token) {
            token = StringUtil.getUniqueCharSequence();
        }
        cacheDao.set(token, user, this.tokenTimeOut, this.tokenTimeUnit);
        cacheDao.set(user.getUsername(), token, this.tokenTimeOut, this.tokenTimeUnit);
        return token;
    }

}
